package com.dwxt.community.service;

import com.dwxt.common.base.*;
import com.dwxt.common.util.*;
import com.dwxt.community.dao.*;
import com.dwxt.community.entity.*;
import com.dwxt.community.entity.vo.*;
import com.github.pagehelper.*;
import org.apache.commons.lang3.*;
import org.springframework.beans.factory.annotation.*;
import org.springframework.stereotype.*;
import org.springframework.transaction.annotation.*;

import java.util.*;
import java.util.stream.*;

/**
 * @author
 * @program: intelligentcity
 * @description: 垃圾投放积分处理
 * @create: 2020/04/14
 */
@Service
public class IntegralService {

    @Autowired
    private TrashIntegralRecoadMapper trashIntegralRecoadMapper;
    @Autowired
    private TrashDeliverMaxMapper trashDeliverMaxMapper;
    @Autowired
    private TrashDeliverTimeMapper trashDeliverTimeMapper;
    @Autowired
    private UserMapper userMapper;

    @Autowired
    private IntegralRuleMapper integralRuleMapper;

    @Autowired
    private IntegralRecordMapper integralRecordMapper;


    //==========================================================================
    //   垃圾投递积分处理
    //==========================================================================
    @Transactional(rollbackFor = Exception.class)
    public synchronized int addIntegral(TrashIntegralRecoad deliver) {

        String delivererId = deliver.getDelivererId();
        if (StringUtils.isBlank(delivererId)) {
            return 0;
        }
        if (deliver.getDeliverWeight() == 0) {
            return 0;
        }
        //获取户主
        User houseOwner = userMapper.selectHouseOwnerByUserId(delivererId);
        int deliveRecoedId = 0;
        Integer integralNum = 0;
        Integer totlaIntegral = 0;
        if (houseOwner != null) {
            //已有积分
            Integer alreadyIntegral = houseOwner.getIntegral();
            totlaIntegral = alreadyIntegral;
            //获取积分规则
            TrashDeliverMax trashDeliverMax = trashDeliverMaxMapper.selectByPrimaryKey(deliver.getTrashType());
            if (ObjectUtils.isEmpty(trashDeliverMax)) {
                return 0;
            }
            //获取应增积分数
            IntegralRule integralRule = integralRuleMapper.selectByExample(null).stream().filter(ir -> ir.getCategory().contains("垃圾分类")).collect(Collectors.toList()).get(0);
            if (ObjectUtils.isEmpty(trashDeliverMax)) {
                //获取默认类型
                trashDeliverMax = trashDeliverMaxMapper.selectDefault();
            }
            //获取积分时间段
            List<TrashDeliverTime> trashDeliverTimes = trashDeliverTimeMapper.selectAll();
            //投递时间处于积分时间段 才可以增加积分
            boolean flag = false;
            for (TrashDeliverTime tdt : trashDeliverTimes) {
                long starTime = DateUtils.stringTime2DateTime(tdt.getStrTime()).getTime();
                long endTime = DateUtils.stringTime2DateTime(tdt.getEndTime()).getTime();
                long currentTimeMillis = deliver.getCreateTime().getTime();
                if (starTime <= currentTimeMillis && currentTimeMillis <= endTime) {
                    flag = true;
                    break;
                }
            }
            //投放次数小于最大投放次数才会增加积分
            if (flag && countIntegralByHouseaddr(houseOwner, deliver.getTrashType(), trashDeliverMax.getWeek()) < trashDeliverMax.getDeliveMax()) {
                //应增积分
                integralNum = integralRule.getIntegral();
                //最终积分  = 已有积分 + 应增积分
                totlaIntegral = alreadyIntegral + integralNum;
                //更新用户积分
                houseOwner.setIntegral(totlaIntegral);
                userMapper.updateByPrimaryKeySelective(houseOwner);
            }
            //积分数增加了才添加记录
            if (integralNum > 0) {
                //新增总积分记录
                createIntegralRecord(IntegralCategory.GARBAGE_DUMP, integralNum, houseOwner.getId(), String.valueOf(deliveRecoedId));
            }
        }

        //新增积分投递记录
        TrashIntegralRecoad trashIntegralRecoad = new TrashIntegralRecoad();
        //设置应获取积分数
        trashIntegralRecoad.setGotIntegral(integralNum);
        //投递后总积分
        User user = userMapper.selectByPrimaryKey(delivererId);
        trashIntegralRecoad.setTotalIntegral(totlaIntegral == 0 ? user.getIntegral() : totlaIntegral);
        //设置投递者
        trashIntegralRecoad.setDelivererId(delivererId);
        //设置户主
        trashIntegralRecoad.setHouseOwnerId(ObjectUtils.isEmpty(houseOwner) ? null : houseOwner.getId());
        //设置投递时间
        trashIntegralRecoad.setCreateTime(deliver.getCreateTime());
        //重量
        trashIntegralRecoad.setDeliverWeight(deliver.getDeliverWeight());
        //垃圾类别
        trashIntegralRecoad.setTrashType(deliver.getTrashType());
        //设备号
        trashIntegralRecoad.setDeviceId(deliver.getDeviceId());

        trashIntegralRecoad.setCommunityId(deliver.getCommunityId() == null ? user.getCommunityId() :
                deliver.getCommunityId());
        trashIntegralRecoad.setCommunityName(StringUtils.isBlank(deliver.getCommunityName()) ? user.getCommunityName() :
                deliver.getCommunityName());
        trashIntegralRecoad.setHouseNumber(StringUtils.isBlank(deliver.getHouseNumber()) ? user.getHouseNumber() :
                deliver.getHouseNumber());
        deliveRecoedId = trashIntegralRecoadMapper.insert(trashIntegralRecoad);
        return deliveRecoedId;
    }

    /**
     * 当日积分次数
     *
     * @param user
     * @return
     */
    public int countIntegralByHouseaddr(User user, Integer type, Integer week) {
        return trashIntegralRecoadMapper.countIntegralByHouseaddr(user, type, week);
    }

    /**
     * 根据家庭记录查询积分记录
     *
     * @param pageNum
     * @param pageSize
     * @param type
     * @param str
     * @param end
     * @return
     */
    public BaseResult getByHomeAddr(Integer pageNum, Integer pageSize, Integer type, String str, String end) {
        String currentUserId = PartyUtil.getCurrentUserId();
        if (StringUtils.isBlank(currentUserId)) {
            return BaseResult.build(StatusCode.USERNAME_INVALID);
        }
        User user = userMapper.selectByPrimaryKey(currentUserId);
        PageHelper.startPage(pageNum, pageSize);
        List<TrashIntegralRecoad> trashIntegralRecoadList = trashIntegralRecoadMapper.selectByHomeAddr(user, type, str, end);
        return BaseResult.ok(new PageInfo<>(trashIntegralRecoadList));
    }

    /**
     * 根据投递者查询积分记录
     */
    public BaseResult getByDeliverer(Integer pageNum, Integer pageSize, Integer type, String str, String end) {
        String currentUserId = PartyUtil.getCurrentUserId();
        if (StringUtils.isBlank(currentUserId)) {
            return BaseResult.build(StatusCode.USERNAME_INVALID);
        }
        PageHelper.startPage(pageNum, pageSize);
        List<TrashIntegralRecoadVo> trashIntegralRecoadList = trashIntegralRecoadMapper.selectByDelivererId(currentUserId, type, str, end);
        return BaseResult.ok(new PageInfo<>(trashIntegralRecoadList));
    }

    /**
     * 当日垃圾投放情况
     *
     * @return
     */
    public BaseResult getTrashTodayData() {
        String currentUserId = PartyUtil.getCurrentUserId();
        if (StringUtils.isBlank(currentUserId)) {
            return BaseResult.build(StatusCode.USERNAME_INVALID);
        }
        User housrOwner = userMapper.selectByPrimaryKey(currentUserId);
        List<TrashDeliverMax> trashDeliverMaxes = trashDeliverMaxMapper.selectByExample(null);
        ArrayList<TrashIntegralRecoadVo> trashIntegralRecoadVos = new ArrayList<>();
        for (TrashDeliverMax tdm : trashDeliverMaxes) {
            TrashIntegralRecoadVo trashIntegralRecoadVo = new TrashIntegralRecoadVo();
            trashIntegralRecoadVo.setAlreadyNum(countIntegralByHouseaddr(housrOwner, tdm.getId(), tdm.getWeek()));
            trashIntegralRecoadVo.setDeliveMax(tdm.getDeliveMax());
            trashIntegralRecoadVo.setTrashName(tdm.getTrashName());
            trashIntegralRecoadVos.add(trashIntegralRecoadVo);
        }
        return BaseResult.ok(trashIntegralRecoadVos);
    }


    /**
     * 当日积分情况
     *
     * @return
     */
    public BaseResult getIntegralDetail() {
        String currentUserId = PartyUtil.getCurrentUserId();
        if (StringUtils.isBlank(currentUserId)) {
            return BaseResult.build(StatusCode.USERNAME_INVALID);
        }
        //户主
        User housrOwner = userMapper.selectHouseOwnerByUserId(currentUserId);
        //如果没有户主，返回自己的积分情况
        if (housrOwner == null) {
            housrOwner = userMapper.selectByPrimaryKey(currentUserId);
        }
        TrashIntegralRecoadVo tirVo = new TrashIntegralRecoadVo();
        //总积分
        tirVo.setTotleIntegral(housrOwner.getIntegral());
        //当天获取积分数
        int countIntegral = trashIntegralRecoadMapper.sumIntegralByHouseaddr(housrOwner, DateUtils.getTodayDate());
        tirVo.setGotIntegralNum(countIntegral);
        tirVo.setAlreadyNum(countIntegral);//用来配合字段错误,避免手机端打包，优先使用gotIntegralNum
        return BaseResult.ok(tirVo);
    }


    /**
     * 积分区间
     *
     * @return
     */
    public List<TrashDeliverTime> getIntegralTimely() {
        return trashDeliverTimeMapper.selectAll();
    }

    /**
     * 垃圾类别列表
     *
     * @return
     */
    public List<TrashDeliverMax> getTrashCategory() {
        return trashDeliverMaxMapper.selectByExample(null);
    }

    //==========================================================================
    //   积分 处理
    //==========================================================================

    public IntegralRule selectRuleByCategory(String category) {
        IntegralRuleExample example = new IntegralRuleExample();
        example.createCriteria().andCategoryEqualTo(category);
        List<IntegralRule> integralRules = integralRuleMapper.selectByExample(example);
        return integralRules.size() > 0 ? integralRules.get(0) : null;
    }

    public void createIntegralRecord(String category, Integer integral, String userId, String relateId) {
        IntegralRecord record = new IntegralRecord();
        record.setCategory(category);
        record.setIntegral(integral);
        record.setUserId(userId);
        record.setYear(DateUtils.getYear(null));
        record.setMonth(DateUtils.getMonth(null));
        record.setDay(DateUtils.getDay(null));
        record.setRelateId(relateId);
        integralRecordMapper.insertSelective(record);
    }

    public List<IntegralRecord> selectIntegralRecordList() {
        IntegralRecordExample example = new IntegralRecordExample();
        example.setOrderByClause("create_time desc");
        example.createCriteria().andUserIdEqualTo(PartyUtil.getCurrentUserId());
        return integralRecordMapper.selectByExample(example);
    }

    public Map<String, Integer> selectMonthIntegral(Integer year, Integer month) {
        return integralRecordMapper.selectMonthIntegral(PartyUtil.getCurrentUserId(), year, month);
    }

    public Integer selectIntegralRank() {
        return integralRecordMapper.selectIntegralRank(PartyUtil.getCurrentUserId());
    }

    //==========================================================================
    //   垃圾分类可视化
    //==========================================================================
    public BaseResult selectTrashRecordList() {
        List<IntegralRecordListVo> integralRecords = integralRecordMapper.selectTopList();
        return BaseResult.ok(integralRecords);
    }


    /**
     * 月积分排行
     *
     * @param type
     */
    public BaseResult selectTotalMonthIntegral(Integer type) {
        //月排行
        if (type == 1) {
            return BaseResult.ok(integralRecordMapper.selectTotalMonthIntegral());
        } else if (type == 2) {
            //年排行
            return BaseResult.ok(integralRecordMapper.selectTotalYearIntegral());
        } else {
            //总排行
            return BaseResult.ok(integralRecordMapper.selectTotalIntegral());
        }
    }

    public int countTodayByCategoryAndUserId(String category, String userId) {
        IntegralRecordExample example = new IntegralRecordExample();
        example.createCriteria().andUserIdEqualTo(userId).andCategoryEqualTo(category)
                .andYearEqualTo(DateUtils.getYear(null))
                .andMonthEqualTo(DateUtils.getMonth(null))
                .andDayEqualTo(DateUtils.getDay(null));
        return ((Long) integralRecordMapper.countByExample(example)).intValue();
    }
}
